package com.doubi;

import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.doubi.vo.AliyunSTS;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Component
public class AliyunOssUtil {

    @Autowired
    private AliyunOss aliyunOss;

    private OSS ossClient;

    private OSS getInstance() {
        if (ossClient == null) {
            synchronized (AliyunOssUtil.class) {
                if (ossClient == null) {
                    ossClient = new OSSClientBuilder().build(aliyunOss.endpoint, aliyunOss.accessKeyId, aliyunOss.accessKeySecret);
                }
            }
        }
        return ossClient;
    }


    /**
     * 上传
     */
    public String upload(InputStream file, String fileName) {
        getInstance().putObject(aliyunOss.bucketName, fileName, file);
        return aliyunOss.domainName + fileName;
    }

    public String upload(ByteArrayInputStream file, String fileName) {
        getInstance().putObject(aliyunOss.bucketName, fileName, file);
        return aliyunOss.domainName + fileName;
    }

    @SneakyThrows
    public String upload(String fileUrl) {
        URL url = new URL(fileUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置连接超时时间
        conn.setConnectTimeout(3000);
        InputStream inputStream = null;
        // 正常响应时获取输入流, 在这里也就是图片对应的字节流
        if (conn.getResponseCode() == 200) {
            inputStream = conn.getInputStream();
            String fileName = IdUtil.simpleUUID() + ".png";
            getInstance().putObject(aliyunOss.bucketName, fileName, inputStream);
            return aliyunOss.domainName + fileName;
        }
        return null;
    }


    public AliyunSTS getSTSToken() {
        String roleSessionName = "session-name";
        String policy = "{\n" +
                "    \"Version\": \"1\", \n" +
                "    \"Statement\": [\n" +
                "        {\n" +
                "            \"Action\": [\n" +
                "                \"oss:*\"\n" +
                "            ], \n" +
                "            \"Resource\": [\n" +
                "                \"acs:oss:*:*:*\" \n" +
                "            ], \n" +
                "            \"Effect\": \"Allow\"\n" +
                "        }\n" +
                "    ]\n" +
                "}";
        try {
            // 构造 default profile（参数留空，无需添加 region ID）
            IClientProfile profile = DefaultProfile.getProfile("",
                    aliyunOss.accessKeyId, aliyunOss.accessKeySecret);
            // 用 profile 构造 client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setEndpoint(aliyunOss.stsEndPoint);
            request.setMethod(MethodType.POST);
            request.setRoleArn(aliyunOss.roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy); // Optional
            final AssumeRoleResponse response = client.getAcsResponse(request);
            System.out.println("Expiration: " + response.getCredentials().getExpiration());
            System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
            System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
            System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
            System.out.println("RequestId: " + response.getRequestId());
            AliyunSTS sts = new AliyunSTS();
            sts.setEndPoint(aliyunOss.endpoint);
            sts.setStsEndPoint(aliyunOss.stsEndPoint);
            sts.setBucketName(aliyunOss.bucketName);
            sts.setAccessKeyId(response.getCredentials().getAccessKeyId());
            sts.setAccessKeySecret(response.getCredentials().getAccessKeySecret());
            sts.setSecurityToken(response.getCredentials().getSecurityToken());
            sts.setRequestId(response.getRequestId());
            sts.setPolicy(Base64.getEncoder().encodeToString(policy.getBytes(StandardCharsets.UTF_8)));
            return sts;
        } catch (ClientException e) {
            System.out.println("Failed：");
            System.out.println("Error code: " + e.getErrCode());
            System.out.println("Error message: " + e.getErrMsg());
            System.out.println("RequestId: " + e.getRequestId());
        }
        return null;
    }

}